﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcShop.Models.Repositories;
using MvcShop.Models.ViewDataModels;
using System.Data.Objects;

namespace MvcShop.Models.Services
{
    public interface IUsersService
    {
        int MinRequiredPasswordLength { get; }

        IEnumerable<UserToRoleModel> GetUserToRole();
        bool ValidateUser(string userName, string password,out int userId);
        void CreateUser(User user);
        int GetUser(string userName, out bool userIsOnline);
        UserInfo GetUserInfoByName(string name);
        bool ChangePassword(string userName, string oldPassword, string newPassword);
        bool ValidateRole(int userId, out Role role);
        IEnumerable<FControllerAction> GetCAR(ICriteria criteria, int page, int pageSize, Order orderExpr, int roleId);
    }

    public class UsersService : ServiceBase, IUsersService
    {
        private const int _minPasswordLength = 6;
        //private UserRepository _userProvider;

        #region IUsersService 成员
        public int MinRequiredPasswordLength
        {
            get { return _minPasswordLength; }
        }

        public IEnumerable<UserToRoleModel> GetUserToRole()
        {
            var query = (from userRole in this.dataContext.UserRoles
                         join user in this.dataContext.Users on userRole.UserId equals user.UserId
                         join role in this.dataContext.Roles on userRole.RoleId equals role.RoleId
                         select new UserToRoleModel { UserRoleId=userRole.UserRoleId, 
                             UserId = userRole.UserId, 
                             RoleId = userRole.RoleId, 
                             UserName = user.UserName, 
                             RolesName = role.RolesName }).ToList();

            return query;
        }

        public bool ValidateUser(string userName, string password,out int userId)
        {
            var query = (from user in dataContext.Users
                         where user.UserName == userName && user.Password == password
                         select user).FirstOrDefault();

            bool has = (query != null);
            if (has)
            {
                userId = query.UserId;
                query.LastLoginIP = CustomerIP.GetIP();
                query.LastLoginTime = DateTime.Now;
                query.LastLogoutTime = DateTime.Now.AddMinutes(30);
                query.LoginTimes += 1;
                this.dataContext.SaveChanges();
            }
            else 
            {
                userId = 0;
            }
            return has;
        }

        public void CreateUser(User user)
        {
            //this.dataContext.SaveChanges();
            throw new NotImplementedException();
        }

        public int GetUser(string userName, out bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public UserInfo GetUserInfoByName(string name)
        {
            int userId = this.dataContext.Users.Where(c => c.UserName == name).Select(c => c.UserId).FirstOrDefault();

            var query = this.dataContext.UserInfos.FirstOrDefault(c => c.UserId == userId);
            if (query == null)
            {
                query = new UserInfo { UserId = userId };
            }

            return query;
        }

        public bool ChangePassword(string userName, string oldPassword, string newPassword)
        {
            var query = (from user in this.dataContext.Users
                         where user.UserName == userName && user.Password == oldPassword
                         select user).FirstOrDefault();

            bool has = (query != null);
            if (has)
            {
                query.Password = newPassword;
                this.dataContext.SaveChanges();
            }
            return has;
        }

        public bool ValidateRole(int userId, out Role role)
        {
            var query = (from userRole in this.dataContext.UserRoles
                         join roles in this.dataContext.Roles on userRole.RoleId equals roles.RoleId
                         where userRole.UserId == userId
                         select roles).FirstOrDefault();

            role = query;
            return query != null ? true : false;
        }

        public IEnumerable<FControllerAction> GetCAR(ICriteria criteria, int page, int pageSize, Order orderExpr, int roleId)
        { 
            if (criteria == null || orderExpr == null)
                throw new ArgumentNullException("criteria");
            var query = dataContext.CreateQuery<ControllerAction>("[ControllerActions]").Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray());

            var result = (from ca in query
                          select new FControllerAction
                          {
                              ControllerActionId = ca.ControllerActionId,
                              ControlerName = ca.ControlerName,
                              Name = ca.Name,
                              ActionDescription = ca.ActionDescription,
                              IsAllowed = (from car in dataContext.ControllerActionRoles
                                           where car.RoleId == roleId && car.ControlerActionId == ca.ControllerActionId
                                           select car.IsAllowed).FirstOrDefault()
                          }).ToList();

            return result;
        }
        #endregion
    }
}
